import cv2
import math
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

# 解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']  = False
#         自定义函数
def milvTransform(c, v, img):
    # 灰度图专属
    h, w = img.shape[0], img.shape[1]
    new_img = np.zeros((h, w))
    after = np.zeros((h, w))
    after = after.astype(float)
    img = img.astype(float)
    for i in range(h):
        for j in range(w):
            img[i, j] = (img[i, j])/255
            after[i, j] = (c * (math.pow(img[i, j],v)))
            after[i, j] = after[i, j]*254
    after = after.astype(np.uint8)
    return after

def binarization(c,v, img):
    # 灰度图专属
    h, w = img.shape[0], img.shape[1]
    new_img = np.zeros((h, w))
    after = np.zeros((h, w))
    after = after.astype(float)
    img = img.astype(float)
    for i in range(h):
        for j in range(w):
            if img[i][j]>c and img[i][j]<v:
                after[i][j] = 255
            else:
                after[i][j] = 0

    after = after.astype(np.uint8)
    return after

def line(img):
    # 灰度图专属
    h, w = img.shape[0], img.shape[1]
    new_img = np.zeros((h, w))
    after = np.zeros((h, w))
    after = after.astype(float)
    img = img.astype(float)
    for i in range(h):
        for j in range(w):
            if img[i][j]<10:
                after[i][j] = 1.5*img[i][j]
            elif img[i][j]<80 and img[i][j]>=10:
                after[i][j] = img[i][j]*3-15
            else:
                after[i][j] = img[i][j]*0.17+211.65
    after = after.astype(np.uint8)
    return after

#处理过程
def linelayer(img):
    h, w = img.shape[0], img.shape[1]
    new_img = np.zeros((h,w,8))
    for i in range(h):
        for j in range(w):
            n = str(np.binary_repr(img[i,j],8))
            for k in range(8):
                new_img[i,j,k] = n[k]
                new_img[i, j, k] = new_img[i,j,k]*255
    new_img = new_img.astype(np.uint8)
    return new_img
# 第一题
# img = cv2.imread('Pic/2/source/Fig0718(a).tif')
# img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#
#
# milv_img = milvTransform(0.7,0.5, img)
# milv_img = cv2.resize(milv_img,(0, 0),fx=0.6,fy=0.6,interpolation=cv2.INTER_NEAREST)
#
# cv2.imshow('milv_img',milv_img)
# cv2.imwrite('Pic/2/2-milvchange.jpg', milv_img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
#
# #绘制幂律函数
# y=[]
# x=np.arange(0,255)
# for i in x:
#     y.append(3*math.pow(i,0.9))
# plt.plot(x,y)
# plt.xlabel('输入灰度级')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'输出灰度级')
# plt.title(r'幂律变换曲线'+r'$\mathbf{s}=\mathbf{0.7}\mathbf{r}^{\mathbf{0.5}}$')
# plt.savefig('Pic/2/2-milvfunction.png',dpi=500)
# plt.show()
#
# plt.hist(img.flatten(), range=(0, 255), bins=256, alpha=0.5, density=True)
# plt.xlabel('r')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'p(r)')
# plt.title(r'增强前的直方图$')
# plt.savefig('Pic/2/2-source.png',dpi=500)
# plt.show()
#
# plt.hist(milv_img.flatten(), range=(0, 255), bins=256, alpha=0.5, density=True)
# plt.xlabel('s')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'p(s)')
# plt.title(r'增强后的直方图$')
# plt.savefig('Pic/2/2-milvhist.png',dpi=500)
# plt.show()

#第二题二值化

# img = cv2.imread('Pic/2/source/Fig0308(a).tif')
# img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#
# linebainry_img = binarization(30, 60,img)
# linebainry_img = cv2.resize(linebainry_img,(0, 0),fx=0.6,fy=0.6,interpolation=cv2.INTER_NEAREST)
#
# cv2.imshow('milv_img',linebainry_img)
# # cv2.imwrite('Pic/2/3-linebainrychange.jpg', linebainry_img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

#第二题线性变换

# img = cv2.imread('Pic/2/source/Fig0308(a).tif')
# img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#
# line_img = line(img)
# line_img = cv2.resize(line_img,(0, 0),fx=0.6,fy=0.6,interpolation=cv2.INTER_NEAREST)
#
# cv2.imshow('line_img',line_img)
# cv2.imwrite('Pic/2/4-linechange.jpg', line_img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
#
# #绘制分段线性函数
# y=[]
# x=np.arange(0,255)
# for i in x:
#     if i < 10:
#         y.append(1.5*i)
#     elif i< 80 and i >= 10:
#          y.append(3 * i-15)
#     else:
#         y.append(0.17 * i+211.65)
# plt.plot(x,y)
# plt.xlabel('输入灰度级')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'输出灰度级')
# plt.title(r'分段线性函数')
# plt.savefig('Pic/2/4-line.png',dpi=500)
# plt.show()
#
# plt.hist(line_img.flatten(), range=(0, 255), bins=256, alpha=0.5, density=True)
# plt.xlabel('s')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'p(s)')
# plt.title(r'增强后的直方图$')
# plt.savefig('Pic/2/4-linehist.png',dpi=500)
# plt.show()

#第三题 分段线性变换

#更改为需要的图片路径
# img = cv2.imread( 'Pic/2/source/Fig0308(a).tif')
# img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
# new_img = linelayer(img)

#依次显示
# for i in range(8):
#     the_img = cv2.resize(new_img[:,:,i], (0, 0), fx=0.6, fy=0.6, interpolation=cv2.INTER_NEAREST)
#     cv2.imwrite('Pic/2/5-layer'+str(i+1)+'.jpg', the_img)
#     cv2.imshow('image',the_img)
#     cv2.waitKey(0)
#
# cv2.destroyAllWindows()
#
# #绘制分段线性函数
# y=[]
# x=np.arange(0,255)
# for i in x:
#     if i > 127:
#         y.append(255)
#     else:
#         y.append(0)
# plt.plot(x,y)
# plt.xlabel('输入灰度级')  # 显示x轴名词，u是更改字符编码。
# plt.ylabel(r'输出灰度级')
# plt.title(r'比特平面分层 变换曲线')
# plt.savefig('Pic/2/5-layerfuncrion.png',dpi=500)
# plt.show()
#
#第四题 直方图均衡

img = cv2.imread( 'Pic/2/source/Fig0718(a).tif')
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
dst = cv2.equalizeHist(img)

dst = cv2.resize(dst, (0, 0), fx=0.6, fy=0.6, interpolation=cv2.INTER_NEAREST)
cv2.imwrite('Pic/2/6-equalize-2.jpg', dst)
cv2.imshow('image',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

plt.hist(dst.flatten(), range=(0, 255), bins=256, alpha=0.5, density=True)
plt.xlabel('s')  # 显示x轴名词，u是更改字符编码。
plt.ylabel(r'p(s)')
plt.title(r'增强后的直方图')
plt.savefig('Pic/2/6-equalizeHist-2.png',dpi=500)
plt.show()


